{ "cells": [ { "cell_type": "markdown", "id": "specific-boulder", "metadata": {}, "source": [ "# Asignación de tareas - Solución" ] }, { "cell_type": "markdown", "id": "written-elephant", "metadata": {}, "source": [ "Tags: Asignación, Variable binaria, Recurso" ] }, { "cell_type": "code", "execution_count": 1, "id": "fe8c0d77", "metadata": { "tags": [ "hide-input", "thebe-init" ] }, "outputs": [], "source": [ "import os\n", "# Por precaución, cambiamos el directorio activo de Python a aquel que contenga este notebook\n", "if \"optimizacion\" in os.listdir():\n", " os.chdir(r\"optimizacion/Formulaciones/6. Asignacion de tareas/\")" ] }, { "cell_type": "markdown", "id": "annoying-circus", "metadata": {}, "source": [ "## Enunciado\n", "\n", "" ] }, { "cell_type": "markdown", "id": "bd1b893a", "metadata": {}, "source": [ "El equipo de Principios de Optimización se encuentra realizando un rediseño estructural del curso. Dado el largo trabajo que este rediseño implica, los integrantes del equipo han definido diez responsabilidades que deben ser ejecutadas. Para esto, el equipo debe decidir cuál es la mejor asignación de responsabilidades a los diferentes integrantes del equipo para el periodo intersemestral. " ] }, { "cell_type": "markdown", "id": "121b89d7", "metadata": {}, "source": [ "Cada uno de los cinco miembros del equipo está en la capacidad de encargarse de cualquiera de estas diez responsabilidades, sin embargo, debido sus preferencias y habilidades, cada uno ha determinado el tiempo (en horas) que le tomará realizar cada una de las responsabilidades que le pueden ser asignadas. Además, cada uno de ellos cuenta con una disponibilidad horaria de acuerdo con su contrato y sus demás compromisos personales. La información descrita anteriormente se encuentra disponible en la Tabla 1. " ] }, { "cell_type": "markdown", "id": "d89526c8", "metadata": {}, "source": [ "

Tabla 1. Tiempos de realización y disponibilidad (en horas)

" ] }, { "cell_type": "markdown", "id": "f0e75259", "metadata": {}, "source": [ "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", "\n", "
Integrantes
Responsabilidades12345
Diseño parciales2575125200250
Diseño tareas7525225250200
Diseño y grabación videos magistrales50125100175225
Diseño talleres magistrales10050250225175
Diseño jupyter notebooks 1251502515050
Grabación videos trabajo asistido1751755010075
Edición videos trabajo asistido 22520017525150
Diseño talleres trabajo asistido 15010075125100
Diseño y grabación videos PulP 2002251507550
Edición videos PulP 25025020050125
Disponibilidad 20015015010075
" ] }, { "cell_type": "markdown", "id": "32d158d9", "metadata": {}, "source": [ "Aparte de hacer un curso agradable y productivo para cada uno de los estudiantes, el equipo del curso se siente motivado y a gusto en el proceso de rediseño. Por lo anterior, cada uno ha definido el índice de preferencia asociado a realizar cada una de las responsabilidades. Este índice se encuentra en una escala de 1 a 10, correspondiendo 1 y 10 a la responsabilidad menos deseada y a la preferida, respectivamente. En la Tabla 2 se presenta esta información." ] }, { "cell_type": "markdown", "id": "1224e1ff", "metadata": {}, "source": [ "

Tabla 2. Preferencias

" ] }, { "cell_type": "markdown", "id": "9a6b8836", "metadata": {}, "source": [ "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", "
Integrantes
Responsabilidades12345
Diseño parciales135810
Diseño tareas319108
Diseño y grabación videos magistrales25479
Diseño talleres magistrales421097
Diseño jupyter notebooks 56162
Grabación videos trabajo asistido77243
Edición videos trabajo asistido 98716
Diseño talleres trabajo asistido 64354
Diseño y grabación videos PulP 89631
Edición videos PulP 1010825
" ] }, { "cell_type": "markdown", "id": "c9af8f63", "metadata": {}, "source": [ "El equipo de Principios de Optimización te ha pedido que plantees y resuelvas un modelo matemático que represente la situación." ] }, { "cell_type": "markdown", "id": "linear-shadow", "metadata": {}, "source": [ "## Formulación\n", "\n", "" ] }, { "cell_type": "markdown", "id": "f08dc1b9", "metadata": {}, "source": [ "**a.** Formula matemáticamente un modelo de optimización de forma general que represente la\n", "situación anterior. Defina clara y rigurosamente: \n", "- Conjuntos\n", "- Parámetros\n", "- Variables de decisión\n", "- Restricciones\n", "- Naturaleza de las variables\n", "- Función objetivo" ] }, { "cell_type": "markdown", "id": "072d50ec", "metadata": {}, "source": [ "### Conjuntos" ] }, { "cell_type": "markdown", "id": "6455b30a", "metadata": {}, "source": [ "- $I$: Integrantes \n", "- $R$: Responsabilidades " ] }, { "cell_type": "markdown", "id": "0675beb9", "metadata": {}, "source": [ "### Parámetros" ] }, { "cell_type": "markdown", "id": "1bd3a567", "metadata": {}, "source": [ "- $t_{ir}$: tiempo que le tomaría al integrante $i\\in I$ realizar la responsabilidad $r\\in R$ \n", "- $d_{i}$: disponibilidad de tiempo del integrante $i\\in I$\n", "- $p_{ir}$: preferencia del integrante $i\\in I$ por realizar la responsabilidad $r\\in R$ " ] }, { "cell_type": "markdown", "id": "d0e37d61", "metadata": {}, "source": [ "### Variables de decisión" ] }, { "cell_type": "markdown", "id": "be82677a", "metadata": {}, "source": [ "- $x_{ir}: \\begin{cases}1\\text{,}&\\text{ si el integrante }i\\in I\\text{ realiza la responsabilidad }r\\in R\\text{;}\\\\ 0\\text{,} & \\text{ d.l.c.} \\end{cases}$" ] }, { "cell_type": "markdown", "id": "north-language", "metadata": {}, "source": [ "### Restricciones" ] }, { "cell_type": "markdown", "id": "216bc3c0", "metadata": {}, "source": [ "Cada responsabilidad se debe asignar a una persona $r \\in R$:" ] }, { "cell_type": "markdown", "id": "5038f55b", "metadata": {}, "source": [ "$$\n", "\\sum_{i\\in I}x_{ir}=1, \\forall r\\in R;\n", "$$" ] }, { "cell_type": "markdown", "id": "c3eae86e", "metadata": {}, "source": [ "Se debe respetar la limitación de tiempo de cada integrante $i\\in I$:" ] }, { "cell_type": "markdown", "id": "a8b51413", "metadata": {}, "source": [ "$$\n", "\\sum_{r\\in R}t_{ir}\\cdot x_{ir}\\le d_i, \\forall i\\in I;\n", "$$" ] }, { "cell_type": "markdown", "id": "descending-testament", "metadata": {}, "source": [ "### Naturaleza de las Variables" ] }, { "cell_type": "markdown", "id": "f64a769f", "metadata": {}, "source": [ "A cada integrante $i\\in I$ solo se le puede asignar (1) o no (0) una responsabilidad $r \\in R$:" ] }, { "cell_type": "markdown", "id": "191418f6", "metadata": {}, "source": [ "$$\n", "x_{ir}\\in\\{0,1\\},\\forall i\\in I, r\\in R.\n", "$$" ] }, { "cell_type": "markdown", "id": "voluntary-couple", "metadata": {}, "source": [ "### Función objetivo" ] }, { "cell_type": "markdown", "id": "f7810831", "metadata": {}, "source": [ "Se debe maximizar la preferencia satisfecha:" ] }, { "cell_type": "markdown", "id": "554d4242", "metadata": {}, "source": [ "$$\n", " \\operatorname{máx}\\ \\sum_{i\\in I}\\sum_{r\\in R}p_{ir}\\cdot x_{ir}\n", "$$" ] }, { "cell_type": "markdown", "id": "geographic-header", "metadata": {}, "source": [ "## Implementación" ] }, { "cell_type": "markdown", "id": "4725d708", "metadata": {}, "source": [ "**b.** Resuelve el modelo planteado utilizando la librería de PuLP en Python. ¿Cuál es la solución óptima del problema? " ] }, { "cell_type": "markdown", "id": "2a1a82c3", "metadata": {}, "source": [ "### Librerías" ] }, { "cell_type": "markdown", "id": "f597d592", "metadata": {}, "source": [ "Importa la librería `pulp` para crear y resolver el modelo." ] }, { "cell_type": "code", "execution_count": 2, "id": "323a0476", "metadata": {}, "outputs": [], "source": [ "import pulp as lp" ] }, { "cell_type": "markdown", "id": "837873b4", "metadata": {}, "source": [ "### Conjuntos" ] }, { "cell_type": "markdown", "id": "48fddac0", "metadata": {}, "source": [ "Define los conjuntos `I` y `R` que representan respectivamente los integrantes y las responsabilidades.\n", "\n", "Recuerda que por conveniencia de preservar el orden de los elementos de los conjuntos, no siempre deberás definirlos con el tipo `set`." ] }, { "cell_type": "code", "execution_count": 3, "id": "d9209bb7", "metadata": {}, "outputs": [], "source": [ "# Integrantes\n", "I = list(range(1, 6))\n", "\n", "# Responsabilidades\n", "R = [\n", " \"Diseño parciales\",\n", " \"Diseño tareas\",\n", " \"Diseño y grabación videos magistrales\",\n", " \"Diseño talleres magistrales\",\n", " \"Diseño jupyter notebooks\",\n", " \"Grabación videos trabajo asistido\",\n", " \"Edición videos trabajo asistido\",\n", " \"Diseño talleres trabajo asistido\",\n", " \"Diseño y grabación videos PuLP\",\n", " \"Edición videos PuLP\",\n", "]" ] }, { "cell_type": "markdown", "id": "8c58ff99", "metadata": {}, "source": [ "### Parámetros" ] }, { "cell_type": "markdown", "id": "d981d80d", "metadata": {}, "source": [ "Define o importa los parámetros del modelo." ] }, { "cell_type": "code", "execution_count": 4, "id": "16df6fb4", "metadata": {}, "outputs": [], "source": [ "# Tiempo que consume i en I en realizar r in R\n", "t = {\n", " (1, \"Diseño parciales\"): 25,\n", " (2, \"Diseño parciales\"): 75,\n", " (3, \"Diseño parciales\"): 125,\n", " (4, \"Diseño parciales\"): 200,\n", " (5, \"Diseño parciales\"): 250,\n", " (1, \"Diseño tareas\"): 75,\n", " (2, \"Diseño tareas\"): 25,\n", " (3, \"Diseño tareas\"): 225,\n", " (4, \"Diseño tareas\"): 250,\n", " (5, \"Diseño tareas\"): 200,\n", " (1, \"Diseño y grabación videos magistrales\"): 50,\n", " (2, \"Diseño y grabación videos magistrales\"): 125,\n", " (3, \"Diseño y grabación videos magistrales\"): 100,\n", " (4, \"Diseño y grabación videos magistrales\"): 175,\n", " (5, \"Diseño y grabación videos magistrales\"): 225,\n", " (1, \"Diseño talleres magistrales\"): 100,\n", " (2, \"Diseño talleres magistrales\"): 50,\n", " (3, \"Diseño talleres magistrales\"): 250,\n", " (4, \"Diseño talleres magistrales\"): 225,\n", " (5, \"Diseño talleres magistrales\"): 175,\n", " (1, \"Diseño jupyter notebooks\"): 125,\n", " (2, \"Diseño jupyter notebooks\"): 150,\n", " (3, \"Diseño jupyter notebooks\"): 25,\n", " (4, \"Diseño jupyter notebooks\"): 150,\n", " (5, \"Diseño jupyter notebooks\"): 50,\n", " (1, \"Grabación videos trabajo asistido\"): 175,\n", " (2, \"Grabación videos trabajo asistido\"): 175,\n", " (3, \"Grabación videos trabajo asistido\"): 50,\n", " (4, \"Grabación videos trabajo asistido\"): 100,\n", " (5, \"Grabación videos trabajo asistido\"): 75,\n", " (1, \"Edición videos trabajo asistido\"): 225,\n", " (2, \"Edición videos trabajo asistido\"): 200,\n", " (3, \"Edición videos trabajo asistido\"): 175,\n", " (4, \"Edición videos trabajo asistido\"): 25,\n", " (5, \"Edición videos trabajo asistido\"): 150,\n", " (1, \"Diseño talleres trabajo asistido\"): 150,\n", " (2, \"Diseño talleres trabajo asistido\"): 100,\n", " (3, \"Diseño talleres trabajo asistido\"): 75,\n", " (4, \"Diseño talleres trabajo asistido\"): 125,\n", " (5, \"Diseño talleres trabajo asistido\"): 100,\n", " (1, \"Diseño y grabación videos PuLP\"): 200,\n", " (2, \"Diseño y grabación videos PuLP\"): 225,\n", " (3, \"Diseño y grabación videos PuLP\"): 150,\n", " (4, \"Diseño y grabación videos PuLP\"): 75,\n", " (5, \"Diseño y grabación videos PuLP\"): 25,\n", " (1, \"Edición videos PuLP\"): 250,\n", " (2, \"Edición videos PuLP\"): 250,\n", " (3, \"Edición videos PuLP\"): 200,\n", " (4, \"Edición videos PuLP\"): 50,\n", " (5, \"Edición videos PuLP\"): 125,\n", "}\n", "\n", "# Preferencia de i en I por r en R\n", "p = {\n", " (1, \"Diseño parciales\"): 1,\n", " (2, \"Diseño parciales\"): 3,\n", " (3, \"Diseño parciales\"): 5,\n", " (4, \"Diseño parciales\"): 8,\n", " (5, \"Diseño parciales\"): 10,\n", " (1, \"Diseño tareas\"): 3,\n", " (2, \"Diseño tareas\"): 1,\n", " (3, \"Diseño tareas\"): 9,\n", " (4, \"Diseño tareas\"): 10,\n", " (5, \"Diseño tareas\"): 8,\n", " (1, \"Diseño y grabación videos magistrales\"): 2,\n", " (2, \"Diseño y grabación videos magistrales\"): 5,\n", " (3, \"Diseño y grabación videos magistrales\"): 4,\n", " (4, \"Diseño y grabación videos magistrales\"): 7,\n", " (5, \"Diseño y grabación videos magistrales\"): 9,\n", " (1, \"Diseño talleres magistrales\"): 4,\n", " (2, \"Diseño talleres magistrales\"): 2,\n", " (3, \"Diseño talleres magistrales\"): 10,\n", " (4, \"Diseño talleres magistrales\"): 9,\n", " (5, \"Diseño talleres magistrales\"): 7,\n", " (1, \"Diseño jupyter notebooks\"): 5,\n", " (2, \"Diseño jupyter notebooks\"): 6,\n", " (3, \"Diseño jupyter notebooks\"): 1,\n", " (4, \"Diseño jupyter notebooks\"): 6,\n", " (5, \"Diseño jupyter notebooks\"): 2,\n", " (1, \"Grabación videos trabajo asistido\"): 7,\n", " (2, \"Grabación videos trabajo asistido\"): 7,\n", " (3, \"Grabación videos trabajo asistido\"): 2,\n", " (4, \"Grabación videos trabajo asistido\"): 4,\n", " (5, \"Grabación videos trabajo asistido\"): 3,\n", " (1, \"Edición videos trabajo asistido\"): 9,\n", " (2, \"Edición videos trabajo asistido\"): 8,\n", " (3, \"Edición videos trabajo asistido\"): 7,\n", " (4, \"Edición videos trabajo asistido\"): 1,\n", " (5, \"Edición videos trabajo asistido\"): 6,\n", " (1, \"Diseño talleres trabajo asistido\"): 6,\n", " (2, \"Diseño talleres trabajo asistido\"): 4,\n", " (3, \"Diseño talleres trabajo asistido\"): 3,\n", " (4, \"Diseño talleres trabajo asistido\"): 5,\n", " (5, \"Diseño talleres trabajo asistido\"): 4,\n", " (1, \"Diseño y grabación videos PuLP\"): 8,\n", " (2, \"Diseño y grabación videos PuLP\"): 9,\n", " (3, \"Diseño y grabación videos PuLP\"): 6,\n", " (4, \"Diseño y grabación videos PuLP\"): 3,\n", " (5, \"Diseño y grabación videos PuLP\"): 1,\n", " (1, \"Edición videos PuLP\"): 10,\n", " (2, \"Edición videos PuLP\"): 10,\n", " (3, \"Edición videos PuLP\"): 8,\n", " (4, \"Edición videos PuLP\"): 2,\n", " (5, \"Edición videos PuLP\"): 5,\n", "}\n", "\n", "# Disponibilidad en tiempo de i en I\n", "d = {\n", " 1: 200,\n", " 2: 150,\n", " 3: 150,\n", " 4: 100,\n", " 5: 75,\n", "}" ] }, { "cell_type": "markdown", "id": "70fd6598", "metadata": {}, "source": [ "### Objeto del modelo" ] }, { "cell_type": "markdown", "id": "aa975e80", "metadata": {}, "source": [ "Construye un problema al que luego agregarás las restricciones y la función objetivo." ] }, { "cell_type": "code", "execution_count": 5, "id": "a1501b81", "metadata": {}, "outputs": [], "source": [ "problema = lp.LpProblem(name=\"Asignación\", sense=lp.LpMinimize)" ] }, { "cell_type": "markdown", "id": "970af788", "metadata": {}, "source": [ "### Variables de decisión" ] }, { "cell_type": "markdown", "id": "1e670ec8", "metadata": {}, "source": [ "Define las variables del problema de manera que estén contenidas en diccionarios indexados en los conjuntos de sus variables respectivas." ] }, { "cell_type": "code", "execution_count": 6, "id": "e1febe93", "metadata": {}, "outputs": [], "source": [ "# Si i en I realiza r en R\n", "x = {\n", " (i, r): lp.LpVariable(\n", " name=f\"{i}_realiza_{r}\", lowBound=0, upBound=None, cat=lp.LpBinary\n", " )\n", " for i in I\n", " for r in R\n", "}" ] }, { "cell_type": "markdown", "id": "f843462c", "metadata": {}, "source": [ "### Función objetivo" ] }, { "cell_type": "markdown", "id": "97df9059", "metadata": {}, "source": [ "Agrega al problema la función objetivo. Recuerda que al definir el problema, ya definiste si este es de maximización o minimización." ] }, { "cell_type": "code", "execution_count": 7, "id": "2fd8a365", "metadata": {}, "outputs": [], "source": [ "problema += sum(p[i, r] * x[i, r] for i in I for r in R), \"satisfaccion_total\"" ] }, { "cell_type": "markdown", "id": "89f524db", "metadata": {}, "source": [ "### Restricciones" ] }, { "cell_type": "markdown", "id": "77e7e409", "metadata": {}, "source": [ "Agrega al problema las restricciones del modelo." ] }, { "cell_type": "code", "execution_count": 8, "id": "f986d5ee", "metadata": {}, "outputs": [], "source": [ "# Se asigna cada tarea a una persona\n", "for r in R:\n", " problema += (\n", " sum(x[i, r] for i in I) == 1,\n", " f\"asigna_responsabilidad_{r}\",\n", " )\n", "\n", "# Se respeta la disponibilidad de horas de i en I\n", "for i in I:\n", " problema += sum(t[i, r] * x[i, r] for r in R) <= d[i], f\"disponibilidad_{i}\"" ] }, { "cell_type": "markdown", "id": "265a2a10", "metadata": {}, "source": [ "### Resolver el problema" ] }, { "cell_type": "markdown", "id": "d7661201", "metadata": {}, "source": [ "Invoca el optimizador. Este paso le asigna un valor a las variables incluidas en las restricciones o función objetivo del modelo." ] }, { "cell_type": "code", "execution_count": 9, "id": "ae811704", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Welcome to the CBC MILP Solver \n", "Version: 2.10.8 \n", "Build Date: May 6 2022 \n", "\n", "command line - cbc /tmp/5d955aaffee34bdeafe337746b55d16f-pulp.mps timeMode elapsed branch printingOptions all solution /tmp/5d955aaffee34bdeafe337746b55d16f-pulp.sol (default strategy 1)\n", "At line 2 NAME MODEL\n", "At line 3 ROWS\n", "At line 20 COLUMNS\n", "At line 271 RHS\n", "At line 287 BOUNDS\n", "At line 338 ENDATA\n", "Problem MODEL has 15 rows, 50 columns and 100 elements\n", "Coin0008I MODEL read with 0 errors\n", "Option for timeMode changed from cpu to elapsed\n", "Continuous objective value is 16 - 0.00 seconds\n", "Cgl0003I 5 fixed, 0 tightened bounds, 0 strengthened rows, 0 substitutions\n", "Cgl0003I 5 fixed, 0 tightened bounds, 1 strengthened rows, 0 substitutions\n", "Cgl0003I 0 fixed, 0 tightened bounds, 1 strengthened rows, 0 substitutions\n", "Cgl0004I processed model has 7 rows, 12 columns (12 integer (12 of which binary)) and 26 elements\n", "Cutoff increment increased from 1e-05 to 0.9999\n", "Cbc0038I Initial state - 0 integers unsatisfied sum - 0\n", "Cbc0038I Solution found of 16\n", "Cbc0038I Before mini branch and bound, 12 integers at bound fixed and 0 continuous\n", "Cbc0038I Mini branch and bound did not improve solution (0.00 seconds)\n", "Cbc0038I After 0.00 seconds - Feasibility pump exiting with objective of 16 - took 0.00 seconds\n", "Cbc0012I Integer solution of 16 found by feasibility pump after 0 iterations and 0 nodes (0.00 seconds)\n", "Cbc0001I Search completed - best objective 16, took 0 iterations and 0 nodes (0.00 seconds)\n", "Cbc0035I Maximum depth 0, 0 variables fixed on reduced cost\n", "Cuts at root node changed objective from 16 to 16\n", "Probing was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "Gomory was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "Knapsack was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "Clique was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "MixedIntegerRounding2 was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "FlowCover was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "TwoMirCuts was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "ZeroHalf was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "\n", "Result - Optimal solution found\n", "\n", "Objective value: 16.00000000\n", "Enumerated nodes: 0\n", "Total iterations: 0\n", "Time (CPU seconds): 0.01\n", "Time (Wallclock seconds): 0.00\n", "\n", "Option for printingOptions changed from normal to all\n", "Total time (CPU seconds): 0.01 (Wallclock seconds): 0.00\n", "\n" ] }, { "data": { "text/plain": [ "1" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "problema.solve()" ] }, { "cell_type": "markdown", "id": "655b238a", "metadata": {}, "source": [ "### Imprimir resultados" ] }, { "cell_type": "markdown", "id": "8a7a8a35", "metadata": {}, "source": [ "Antes de estudiar el óptimo del modelo, identifica en el estado del optimizador si pudo resolver el problema." ] }, { "cell_type": "code", "execution_count": 10, "id": "whole-trust", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Estado del optimizador: Optimal'" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f\"Estado del optimizador: {lp.LpStatus[problema.status]}\"" ] }, { "cell_type": "markdown", "id": "ea6fe01e", "metadata": {}, "source": [ "Identifica también el valor de la función objetivo." ] }, { "cell_type": "code", "execution_count": 11, "id": "11b75d2c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Satisfacción total: 16.0'" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f\"Satisfacción total: {lp.value(problema.objective)}\"" ] }, { "cell_type": "markdown", "id": "6e59d608", "metadata": {}, "source": [ "Por último, imprime de manera estructurada el valor de las variables de decisión y otras expresiones de interés." ] }, { "cell_type": "code", "execution_count": 13, "id": "ad53e1be", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Integrante 1:\n", "\t Diseño parciales\n", "\t Diseño y grabación videos magistrales\n", "Integrante 2:\n", "\t Diseño tareas\n", "\t Diseño talleres magistrales\n", "Integrante 3:\n", "\t Diseño jupyter notebooks\n", "\t Grabación videos trabajo asistido\n", "\t Diseño talleres trabajo asistido\n", "Integrante 4:\n", "\t Edición videos trabajo asistido\n", "\t Edición videos PuLP\n", "Integrante 5:\n", "\t Diseño y grabación videos PuLP\n" ] } ], "source": [ "for i in I:\n", " print(f\"Integrante {i}:\")\n", " for r in R:\n", " if lp.value(x[i, r]) >= 0.5:\n", " print(\"\\t\", r)" ] }, { "cell_type": "markdown", "id": "86a97bde", "metadata": {}, "source": [ "## Créditos" ] }, { "cell_type": "markdown", "id": "hired-insulation", "metadata": {}, "source": [ "Equipo Principios de Optimización
\n", "Autores: Juan Felipe Rengifo
\n", "Desarrollo: Juan Felipe Rengifo, Alejandro Mantilla
\n", "Última fecha de modificación: 08/04/2023" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.0" } }, "nbformat": 4, "nbformat_minor": 5 }